package com.tuanchau.android.englishtooltip.service;

import java.util.ArrayList;
import java.util.Vector;

import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.IBinder;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;

import com.tuanchau.android.englishtooltip.Global;
import com.tuanchau.android.englishtooltip.R;
import com.tuanchau.android.englishtooltip.database.DatabaseManager;
import com.tuanchau.android.englishtooltip.database.WordStruct;
import com.tuanchau.android.englishtooltip.ui.activity.ListWordActivity;
import com.tuanchau.android.englishtooltip.ui.activity.SettingActivity;
import com.tuanchau.android.englishtooltip.ui.widget.TooltipWidget;

public class UpdateService extends Service {

	private int count, delay, order, curIndex;
	private Vector<Integer> idList;
	private DatabaseManager db;
	private SharedPreferences pref;
	private WordStruct curWord;
	private Bitmap bitmap;
	private boolean updateWordFlag;
	private boolean updateSettingFlag;
	private boolean isShowToast;
	private Intent intentOpenActivity;
	private ComponentName thisWidget;
	private RemoteViews view;
	private ArrayList<Bitmap> bitmapList;
	private int[] pixels;

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		init();

		buildUpdateWidget();
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		Log.d("Update service", "con heo : onDestroy");
	}

	private void init() {
		if (db == null) {
			db = new DatabaseManager(getApplicationContext());
			idList = db.getIds();

			pref = getSharedPreferences(Global.PREF_FILE_NAME, MODE_PRIVATE);

			count = 0;
			delay = pref.getInt(Global.PREF_KEY_DELAY, 5);

			order = pref.getInt(Global.PREF_KEY_PLAY_ORDER, 0);

			isShowToast = pref.getBoolean(Global.PREF_KEY_SHOW_TOAST, false);
			curIndex = -1;
			bitmapList = new ArrayList<Bitmap>(3);
			if (idList.size() == 0) {
				// Intent i = new Intent(getApplicationContext(),
				// ListWordManager.class);
				// startActivity(i);
			}
		}
	}

	private void buildUpdateWidget() {
		updateWordFlag = pref.getBoolean(Global.PREF_KEY_UPDATE_WORD, false);
		updateSettingFlag = pref.getBoolean(Global.PREF_KEY_UPDATE_SETTING,
				false);

		if (updateWordFlag) {
			updateWord();
		}

		if (updateSettingFlag) {
			updateSetting();
		}
		// show new word
		if (count == 0) {
			if (view == null) {
				view = new RemoteViews(getPackageName(), R.layout.widget_layout);
			}
			if (curWord == null && idList.size() > 0) {
				curWord = nextWord();
			}

			// Bitmap oBitmap = bitmap;
			if (idList.size() > 0) {
				if (curWord == null) {
					updateWord();
					curWord = firstWord();
				}
				if (curWord == null) {
					displayDefaultWord();
				} else {
					diplayNextWord2();
					pref.edit()
							.putInt(Global.PREF_KEY_CURRENT_INDEX, curWord.id)
							.commit();
					pref.edit()
							.putString(Global.PREF_KEY_CURRENT_WORD,
									curWord.word).commit();
				}

			} else {
				displayDefaultWord();
			}

			setupClickPending();

			if (thisWidget == null) {
				thisWidget = new ComponentName(this, TooltipWidget.class);
			}

			AppWidgetManager manager = AppWidgetManager.getInstance(this);
			int[] appIds = manager.getAppWidgetIds(thisWidget);
			for (int id : appIds) {
				Log.d("Update Service", "con heo : id = " + id);
			}
			if (bitmap != null && bitmap.isRecycled()) {
				Log.d("Update Service", "con heo : bitmap is recycled");
			}

			manager.updateAppWidget(thisWidget, view);
			// if(oBitmap != null && !oBitmap.isRecycled()) {
			// oBitmap.recycle();
			// oBitmap = null;
			// }

		} else if (count == 1) {
			// get next word to display
			if (idList.size() > 0) {
				curWord = nextWord();
			}
		}

		// reset count
		count++;
		if (count >= delay) {
			count = 0;
		}

	}

	private void displayDefaultWord() {
		view.setTextViewText(R.id.widget_mean, "Englis is EASY!");
		view.setTextViewText(R.id.widget_word, "EnglishTip");
		view.setImageViewResource(R.id.widget_image, R.drawable.icon);
	}

	private void diplayNextWord() {
		view.setTextViewText(R.id.widget_word, curWord.getWordWithType());
		// view.setTextViewText(R.id.widget_pronunciation, "/" + curWord.pron
		// + "/");
		view.setTextViewText(R.id.widget_mean, curWord.mean);

		if (curWord.image != null) {

			byte[] buffer = new byte[curWord.image.length];
			for (int i = 0; i < buffer.length; i++) {
				buffer[i] = curWord.image[i];
			}

			Bitmap oBitmap = bitmap;

			bitmap = BitmapFactory.decodeByteArray(buffer, 0, buffer.length);
			bitmapList.add(bitmap);
			// if(bitmapList.size() > 2) {
			// Bitmap bm = bitmapList.get(0);
			// bitmapList.remove(0);
			// if(bm!= null && !bm.isRecycled()) {
			// Log.d("Update Service", "con heo : do recycle");
			// bm.recycle();
			// bm = null;
			// }
			// }
			// if(bitmap == null || bitmap.isRecycled()) {
			// Log.d("Update service",
			// "con heo : bitmap is recycled : on update");
			// bitmap = BitmapFactory.decodeByteArray(buffer, 0,
			// buffer.length);
			// }
			view.setImageViewBitmap(R.id.widget_image, bitmap);

			// if(oBitmap != null && !oBitmap.isRecycled()) {
			// oBitmap.recycle();
			// oBitmap = null;
			// }
		} else {

			view.setImageViewResource(R.id.widget_image,
					R.drawable.english_tip_icon_100);
			bitmap = null;
			if (bitmap != null && !bitmap.isRecycled()) {
				bitmap.recycle();
				bitmap = null;
			}
		}
		if (isShowToast) {
			Toast.makeText(getApplicationContext(),
					curWord.word + " : " + curWord.mean, 750).show();
		}

	}

	private void diplayNextWord2() {
		view.setTextViewText(R.id.widget_word, curWord.getWordWithType());
		// view.setTextViewText(R.id.widget_pronunciation, "/" + curWord.pron
		// + "/");
		view.setTextViewText(R.id.widget_mean, curWord.mean);

		if (curWord.image != null) {

			byte[] buffer = new byte[curWord.image.length];
			for (int i = 0; i < buffer.length; i++) {
				buffer[i] = curWord.image[i];
			}
			Bitmap oBitmap = BitmapFactory.decodeByteArray(buffer, 0,
					buffer.length);
			pixels = new int[oBitmap.getWidth() * oBitmap.getHeight()];
			oBitmap.getPixels(pixels, 0, oBitmap.getWidth(), 0, 0,
					oBitmap.getWidth(), oBitmap.getHeight());
			if(bitmap == null) {
				bitmap = Bitmap.createBitmap(oBitmap.getWidth(), oBitmap.getHeight(), Bitmap.Config.ARGB_8888);
			}
			
			bitmap.setPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
			
			
			view.setImageViewBitmap(R.id.widget_image, bitmap);

			if (oBitmap != null && !oBitmap.isRecycled()) {
				oBitmap.recycle();
				oBitmap = null;
			}
		} else {

			view.setImageViewResource(R.id.widget_image,
					R.drawable.english_tip_icon_100);
			bitmap = null;
			if (bitmap != null && !bitmap.isRecycled()) {
				bitmap.recycle();
				bitmap = null;
			}
		}
		if (isShowToast) {
			Toast.makeText(getApplicationContext(),
					curWord.word + " : " + curWord.mean, 750).show();
		}

	}

	private void setupClickPending() {
		if (intentOpenActivity == null) {
			intentOpenActivity = new Intent(getApplicationContext()
					.getApplicationContext(), ListWordActivity.class);
			intentOpenActivity.setAction(Global.ACTION_OPEN_WORD_DETAIL);
			PendingIntent piOpen = PendingIntent.getActivity(
					getApplicationContext().getApplicationContext(),
					Global.REQUEST_TO_LISTWORD_MANAGER, intentOpenActivity, 0);
			view.setOnClickPendingIntent(R.id.widget_word, piOpen);
			view.setOnClickPendingIntent(R.id.widget_mean, piOpen);
			// --------speech--------//
			Intent speechIntent = new Intent(getApplicationContext(),
					SpeechService.class);
			speechIntent.setAction(Global.ACTION_SPEECH);
			PendingIntent piSpeech = PendingIntent.getService(
					getApplicationContext(), Global.REQUEST_TO_SPEECH_WORD,
					speechIntent, 0);
			view.setOnClickPendingIntent(R.id.widget_image, piSpeech);
			// --------setting------//
			Intent settingInent = new Intent(getApplicationContext(),
					SettingActivity.class);
			PendingIntent piSetting = PendingIntent.getActivity(
					getApplicationContext(), Global.REQUEST_TO_SETTING,
					settingInent, 0);
			view.setOnClickPendingIntent(R.id.widget_setting, piSetting);
			// --------add----------//
			Intent addIntent = new Intent(getApplicationContext(),
					ListWordActivity.class);
			addIntent.setAction(Global.ACTION_ADD_WORD);
			PendingIntent piAdd = PendingIntent.getActivity(
					getApplicationContext(),
					Global.REQUEST_TO_LISTWORD_MANAGER, addIntent, 0);
			view.setOnClickPendingIntent(R.id.widget_add, piAdd);
		}
	}

	private WordStruct firstWord() {
		curIndex = -1;
		return nextWord();
	}

	// get next word
	private WordStruct nextWord() {
		switch (order) {
		case Global.ORDER_TOP_DOWN:
			curIndex = curIndex + 1;
			if (curIndex >= idList.size())
				curIndex = 0;
			break;
		case Global.ORDER_BOTTOM_UP:
			curIndex = curIndex - 1;
			if (curIndex < 0)
				curIndex = idList.size() - 1;
			break;
		case Global.ORDER_RANDOM:
			curIndex = (int) (Math.random() * Integer.MAX_VALUE)
					% idList.size();
			break;
		}

		return db.getAtId(idList.get(curIndex));
	}

	// update setting when flag is true, set flag to false
	private void updateSetting() {
		delay = pref.getInt(Global.PREF_KEY_DELAY, 5);
		order = pref.getInt(Global.PREF_KEY_PLAY_ORDER, 0);
		isShowToast = pref.getBoolean(Global.PREF_KEY_SHOW_TOAST, false);
		pref.edit().putBoolean(Global.PREF_KEY_UPDATE_SETTING, false).commit();
	}

	// update word list when flag is true, set flag to false
	private void updateWord() {
		idList = db.getIds(); // set other mode play
		pref.edit().putBoolean(Global.PREF_KEY_UPDATE_WORD, false).commit();
	}

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;

	}

}
